from typing import Any, Dict, Generic, Type, TypeVar, List
from fastapi import HTTPException

from utils.mysql import Base
from sqlalchemy import select, update, delete, text, func

ModelType = TypeVar('ModelType', bound=Base)

# 通用增删改查积累
class CRUDModel(Generic[ModelType]):

    def __init__(self, model: Type[ModelType]):
        self.model = model

    def getModel(self):
        return self.model

    def get_by_id(self, db, pk: int = None) -> ModelType:
        """
        通过主键 id 获取一条数据

        :param db:
        :param pk: id
        :return:
        """
        return db.query(self.model).filter(self.model.id == pk).first()
    def get_count(self, db, where):
        """
        查询数量

        :param db:
        :param where: 查询条件
        :return:
        """
        return db.query(self.model).filter_by(**where).count()
    def get_page(self, db, where, page, limit):
        """
        查询分页数据

        :param db: 数据库对象
        :param where: 查询条件
        :return: list
        """
        return  db.query(self.model).offset((page-1)*limit).limit(limit).all()
    
    def create(self, db, data: dict) -> None:
        """
        新增一条数据, 返回ID（数据库ID必须是自动递增）

        :param db:
        :param data:
        :return:
        """
        create_data = self.model(**data)
        db.add(create_data)
        db.commit()
        res = db.execute(text("SELECT LAST_INSERT_ID() as last_id"))
        print(res)
        return res.first()
        
    def update(self, db, data: dict) -> None:
        """
        修改记录

        :param db:
        :param data:
        :return:
        """
        r = db.query(self.model).filter(self.model.id==data['id']).update(data)
        db.commit()
        return r
    def delete(self, db, pk: int):
        """
        删除记录

        :param db:
        :param pk:
        :return:
        """
        r = db.query(self.model).filter(self.model.id==pk).delete()
        db.commit()
        return r


class BaseDao():
     # 通过ID查询
    def get_by_id(self, pk: int = None) -> ModelType:
        """
        通过主键 id 获取一条数据

        :param db:
        :param pk:
        :return:
        """
        try:
            return self.model.get_by_id(self.db, pk)
        except Exception as e:
            raise HTTPException(status_code=500, detail=str(e))
            
    def get_page(self, where:dict, page:int, limit:int):
        """
        分页查询

        :param db:
        :param where:
        :return:
        """
        try:
            total = self.model.get_count(self.db, where)
            rows  = self.model.get_page(self.db, where, page, limit)
            return {"total": total, "rows": rows}
        except Exception as e:
            raise HTTPException(status_code=500, detail=str(e))

    def add(self, data) -> int :
        """
        新增一条数据, 返回ID

        :param last_id:
        :param data:
        :param db:
        :return:
        """
        try:
            return self.model.create(self.db, data)
        except Exception as e:
            raise HTTPException(status_code=500, detail=str(e))
        
    def edit(self, data):
        """
        修改一条数据

        :param db:
        :param pk:
        :param data:
        :return:
        """
        try:
            return self.model.update(self.db, data)
        except Exception as e:
            raise HTTPException(status_code=500, detail=str(e))
        
    def delete(self, pk):
        """
        删除一条数据

        :param db:
        :param pk:
        :return:
        """
        try:
            return self.model.delete(self.db, pk)
        except Exception as e:
            raise HTTPException(status_code=500, detail=str(e))



        